package com.meituan.catering.management.order.biz.model.converter;

import com.google.common.collect.Lists;
import com.meituan.catering.management.order.api.http.model.enumeration.CateringOrderItemStatusEnum;
import com.meituan.catering.management.order.biz.model.request.AdjustCateringOrderBizRequest;
import com.meituan.catering.management.order.biz.model.request.PlaceCateringOrderBizRequest;
import com.meituan.catering.management.order.biz.model.request.PrepareCateringOrderBizRequest;
import com.meituan.catering.management.order.biz.model.request.ProduceCateringOrderBizRequest;
import com.meituan.catering.management.order.dao.model.CateringOrderItemDO;
import com.meituan.catering.management.order.remote.model.response.ProductDetailRemoteResponse;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Believe
 * Date 2022/5/30 17:14
 */
public class CateringOrderItemDOConverter {
    /**
     * 将请求信息、订单id、用户信息、商品信息转换为CateringOrderItemDO对象
     *
     * @param placeCateringOrderBizRequest 下单请求
     * @param orderId                      订单id
     * @param tenantId                     租户id
     * @param productMap                   RPC商品信息
     * @return
     */
    public static List<CateringOrderItemDO> toCateringOrderItemDO(PlaceCateringOrderBizRequest placeCateringOrderBizRequest, Long orderId, Long tenantId, Map<Long, ProductDetailRemoteResponse> productMap) {
        List<CateringOrderItemDO> cateringOrderItemDOList = Lists.newLinkedList();
        for (PlaceCateringOrderBizRequest.Item item : placeCateringOrderBizRequest.getItems()) {
            if (productMap.containsKey(item.getProductId())) {
                ProductDetailRemoteResponse productRes = productMap.get(item.getProductId());
                CateringOrderItemDO cateringOrderItemDO = new CateringOrderItemDO();
                cateringOrderItemDO.setTenantId(tenantId);
                cateringOrderItemDO.setOrderId(orderId);
                cateringOrderItemDO.setSeqNo(item.getSeqNo());
                cateringOrderItemDO.setStatus(CateringOrderItemStatusEnum.PLACED);
                cateringOrderItemDO.setPlaceQuantity(item.getQuantity());
                cateringOrderItemDO.setProduceQuantity(new BigDecimal(0));
                cateringOrderItemDO.setLatestQuantity(item.getQuantity());
                cateringOrderItemDO.setProductId(item.getProductId());
                cateringOrderItemDO.setProductNameOnPlace(productRes.getName());
                cateringOrderItemDO.setProductUnitPriceOnPlace(new BigDecimal(productRes.getUnitPrice()));
                cateringOrderItemDO.setProductUnitOfMeasureOnPlace(productRes.getUnitOfMeasure());
                cateringOrderItemDO.setProductMethodId(item.getProductMethodId());
                CateringOrderItemDO itemDO = toName(item, productRes.getMethodGroups());
                cateringOrderItemDO.setProductMethodGroupNameOnPlace(itemDO.getProductMethodGroupNameOnPlace());
                cateringOrderItemDO.setProductMethodNameOnPlace(itemDO.getProductMethodNameOnPlace());
                cateringOrderItemDOList.add(cateringOrderItemDO);
            }
        }
        return cateringOrderItemDOList;
    }

    /**
     * 加退菜：将请求信息、订单id、用户信息、商品信息转换为CateringOrderItemDO对象
     *
     * @param items             加退菜请求中item集合
     * @param orderId           订单id
     * @param tenantId          租户id
     * @param remoteResponseMap RPC商品信息
     * @return
     */
    public static List<CateringOrderItemDO> toCateringOrderItemDO(List<AdjustCateringOrderBizRequest.Item> items, Long orderId, Long tenantId, Map<Long, ProductDetailRemoteResponse> remoteResponseMap) {
        List<CateringOrderItemDO> orderItemDOList = Lists.newLinkedList();
        for (AdjustCateringOrderBizRequest.Item item : items) {
            CateringOrderItemDO cateringOrderItemDO = new CateringOrderItemDO();
            ProductDetailRemoteResponse remoteResponse = remoteResponseMap.get(item.getProductId());
            cateringOrderItemDO.setTenantId(tenantId);
            cateringOrderItemDO.setOrderId(orderId);
            cateringOrderItemDO.setSeqNo(item.getSeqNo());
            cateringOrderItemDO.setVersion(item.getVersion());
            cateringOrderItemDO.setStatus(CateringOrderItemStatusEnum.PLACED);
            cateringOrderItemDO.setPlaceQuantity(item.getQuantityOnAdjustment());
            cateringOrderItemDO.setProduceQuantity(new BigDecimal(0));
            cateringOrderItemDO.setLatestQuantity(item.getQuantityOnAdjustment());
            cateringOrderItemDO.setProductId(item.getProductId());
            cateringOrderItemDO.setProductNameOnPlace(remoteResponse.getName());
            cateringOrderItemDO.setProductUnitPriceOnPlace(new BigDecimal(remoteResponse.getUnitPrice()));
            cateringOrderItemDO.setProductUnitOfMeasureOnPlace(remoteResponse.getUnitOfMeasure());
            cateringOrderItemDO.setProductMethodId(item.getProductMethodId());
            CateringOrderItemDO itemDO = toName(item, remoteResponse.getMethodGroups());
            cateringOrderItemDO.setProductMethodGroupNameOnPlace(itemDO.getProductMethodGroupNameOnPlace());
            cateringOrderItemDO.setProductMethodNameOnPlace(itemDO.getProductMethodNameOnPlace());
            orderItemDOList.add(cateringOrderItemDO);
        }
        return orderItemDOList;
    }

    /**
     * 制作：参数转换为CateringOrderItemDO对象
     *
     * @param orderId      订单id
     * @param items        制作请求中的item集合
     * @param orderItemDOS 数据库中查询的订单子项集合
     * @return
     */
    public static List<CateringOrderItemDO> toCateringOrderItemDO(Long orderId, List<PrepareCateringOrderBizRequest.Item> items,
                                                                  List<CateringOrderItemDO> orderItemDOS) {
        List<CateringOrderItemDO> orderItemDOList = Lists.newLinkedList();
        Map<String, CateringOrderItemDO> orderItemDOMap = orderItemDOS.stream().collect(Collectors.toMap(CateringOrderItemDO::getSeqNo, item -> item));
        for (PrepareCateringOrderBizRequest.Item item : items) {
            if (orderItemDOMap.containsKey(item.getSeqNo())) {
                CateringOrderItemDO orderItemDO = orderItemDOMap.get(item.getSeqNo());
                orderItemDO.setOrderId(orderId);
                orderItemDO.setStatus(CateringOrderItemStatusEnum.PREPARING);
                orderItemDO.setSeqNo(item.getSeqNo());
                orderItemDO.setVersion(item.getVersion());
                orderItemDOList.add(orderItemDO);
            }
        }
        return orderItemDOList;
    }

    /**
     * 出餐：参数转换为CateringOrderItemDO对象
     *
     * @param orderId      订单id
     * @param items        制作请求中item集合
     * @param orderItemDOS 数据库中查询出来的订单子项集合
     * @return
     */
    public static List<CateringOrderItemDO> toCateringOrderItem(Long orderId, List<ProduceCateringOrderBizRequest.Item> items,
                                                                List<CateringOrderItemDO> orderItemDOS) {
        List<CateringOrderItemDO> orderItemDOList = Lists.newLinkedList();
        Map<String, CateringOrderItemDO> orderItemDOMap = orderItemDOS.stream().collect(Collectors.toMap(CateringOrderItemDO::getSeqNo, item -> item));
        for (ProduceCateringOrderBizRequest.Item item : items) {
            if (orderItemDOMap.containsKey(item.getSeqNo())) {
                CateringOrderItemDO orderItemDO = orderItemDOMap.get(item.getSeqNo());
                orderItemDO.setOrderId(orderId);
                if (item.getQuantityOnProduce().add(orderItemDO.getProduceQuantity()).equals(orderItemDO.getPlaceQuantity())) {
                    orderItemDO.setStatus(CateringOrderItemStatusEnum.PREPARED);
                }
                orderItemDO.setSeqNo(item.getSeqNo());
                orderItemDO.setVersion(item.getVersion());
                orderItemDO.setProduceQuantity(item.getQuantityOnProduce().add(orderItemDO.getProduceQuantity()));
                orderItemDOList.add(orderItemDO);
            }
        }
        return orderItemDOList;
    }

    private static CateringOrderItemDO toName(AdjustCateringOrderBizRequest.Item item, List<ProductDetailRemoteResponse.MethodGroup> methodGroups) {
        CateringOrderItemDO cateringOrderItemDO = new CateringOrderItemDO();
        for (ProductDetailRemoteResponse.MethodGroup methodGroup : methodGroups) {
            for (ProductDetailRemoteResponse.MethodGroup.Option option : methodGroup.getOptions()) {
                if (item.getProductMethodId().equals(option.getId())) {
                    cateringOrderItemDO.setProductMethodGroupNameOnPlace(methodGroup.getName());
                    cateringOrderItemDO.setProductMethodNameOnPlace(option.getName());
                }
            }
        }
        return cateringOrderItemDO;
    }

    private static CateringOrderItemDO toName(PlaceCateringOrderBizRequest.Item item, List<ProductDetailRemoteResponse.MethodGroup> methodGroups) {
        CateringOrderItemDO cateringOrderItemDO = new CateringOrderItemDO();
        for (ProductDetailRemoteResponse.MethodGroup methodGroup : methodGroups) {
            for (ProductDetailRemoteResponse.MethodGroup.Option option : methodGroup.getOptions()) {
                if (item.getProductMethodId().equals(option.getId())) {
                    cateringOrderItemDO.setProductMethodGroupNameOnPlace(methodGroup.getName());
                    cateringOrderItemDO.setProductMethodNameOnPlace(option.getName());
                }
            }
        }
        return cateringOrderItemDO;
    }
}
